#include "snowboy/snowboy-detect-c-wrapper.h"
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h> // sleep 和 usleep
#include "record.h"
#include "stt.h"
#include "chat.h"
#include "config.h"
#include "http.h"
#include "tts.h"
#include "play.h"
#include <gpiod.h>
#include "control.h"

#define SILENCE_THRESHOLD 2 // 静音持续时间阈值（秒）
#define VOLUME_STEP 25      // 音量调整步长

void handle_error(const char *message, snd_pcm_t *capture, SnowboyDetect *detector) {
    perror(message);
    if (capture) {
        record_close(capture);
    }
    if (detector) {
        SnowboyDetectDestructor(detector);
    }
    exit(EXIT_FAILURE);
}

int execute_command(const char *command, FILE *ac_fp, FILE *led_fp1, FILE *led_fp2, FILE *led_fp3, int *hazard_lights_on, long *volume) {
    if (strstr(command, "打开空调") != NULL) {
        fprintf(ac_fp, "255");
        fflush(ac_fp);
        text_to_speech("空调已打开");
        return 1;
    } else if (strstr(command, "关闭空调") != NULL) {
        fprintf(ac_fp, "0");
        fflush(ac_fp);
        text_to_speech("空调已关闭");
        return 1;
    } else if (strstr(command, "打开车内灯光") != NULL) {
        fprintf(led_fp2, "1");
        fflush(led_fp2);
        text_to_speech("车内灯光已打开");
        return 1;
    } else if (strstr(command, "关闭车内灯光") != NULL) {
        fprintf(led_fp2, "0");
        fflush(led_fp2);
        text_to_speech("车内灯光已关闭");
        return 1;
    } else if (strstr(command, "打开双闪") != NULL) {
        *hazard_lights_on = 1;
        text_to_speech("双闪已打开");
        return 1;
    } else if (strstr(command, "关闭双闪") != NULL) {
        *hazard_lights_on = 0;
        fprintf(led_fp1, "0");
        fflush(led_fp1);
        fprintf(led_fp3, "0");
        fflush(led_fp3);
        text_to_speech("双闪已关闭");
        return 1;
    } else if (strstr(command, "增大音量") != NULL) {
        *volume += VOLUME_STEP;
        set_playback_volume("hw:0", "Analog", *volume);
        char response[50];
        snprintf(response, sizeof(response), "音量已增加到 %ld", *volume);
        text_to_speech(response);
        return 1;
    } else if (strstr(command, "减小音量") != NULL) {
        *volume -= VOLUME_STEP;
        set_playback_volume("hw:0", "Analog", *volume);
        char response[50];
        snprintf(response, sizeof(response), "音量已减小到 %ld", *volume);
        text_to_speech(response);
        return 1;
    } else {
        return 0;
    }
}

int main() {
    // 创建snowboy检测器
    SnowboyDetect *detector = SnowboyDetectConstructor("common.res", "model.pmdl");
    if (!detector) {
        fprintf(stderr, "Error creating Snowboy detector\n");
        return EXIT_FAILURE;
    }

    // 设置检测器的灵敏度
    SnowboyDetectSetSensitivity(detector, "0.6");

    // 获取检测器支持的音频数据参数
    int bits = SnowboyDetectBitsPerSample(detector);
    int channels = SnowboyDetectNumChannels(detector);
    int rate = SnowboyDetectSampleRate(detector);

    printf("采样深度: %d\n", bits);
    printf("声道数量: %d\n", channels);
    printf("采样频率: %d\n", rate);

    // 打开音频采集设备
    snd_pcm_uframes_t period = 999;
    snd_pcm_t *capture = record_open("hw:0,1", SND_PCM_FORMAT_S16_LE, channels, rate, &period);
    if (!capture) {
        SnowboyDetectDestructor(detector);
        return EXIT_FAILURE;
    }

    char *buffer = malloc(snd_pcm_frames_to_bytes(capture, period)); // 分配缓冲区
    if (!buffer) {
        handle_error("malloc buffer", capture, detector);
    }

    int recording = 0;        // 录音状态标志
    time_t silence_start = 0; // 静音开始时间
    FILE *pcm_file = NULL;    // 内存文件
    char *audio = NULL;       // 音频缓冲区
    size_t audio_size = 0;    // 音频大小
    int hazard_lights_on = 0; // 双闪灯状态标志
    time_t last_blink_time = 0; // 上一次闪烁时间
    int blink_state = 0;      // 闪烁状态（0或1）

    // 读取配置文件中的平台密钥
    cJSON *config = read_config("config.json");
    if (!config) {
        handle_error("读取配置文件失败", capture, detector);
    }

    cJSON *authtoken = cJSON_GetObjectItem(config, "authtoken");
    if (!authtoken) {
        fprintf(stderr, "配置文件错误: 找不到 'authtoken' 字段\n");
        cJSON_Delete(config);
        handle_error("配置文件错误", capture, detector);
    }

    // 创建会话
    char *conv_id = create_conversation(authtoken->valuestring);
    if (!conv_id) {
        handle_error("创建会话失败", capture, detector);
    }

    printf("conv_id: %s\n", conv_id);

    // 打开空调和LED设备文件
    FILE *ac_fp = fopen("/sys/class/hwmon/hwmon1/pwm1", "w");
    FILE *led_fp1 = fopen("/sys/class/leds/led1/brightness", "w");
    FILE *led_fp2 = fopen("/sys/class/leds/led2/brightness", "w");
    FILE *led_fp3 = fopen("/sys/class/leds/led3/brightness", "w");

    if (ac_fp == NULL || led_fp1 == NULL || led_fp2 == NULL || led_fp3 == NULL) {
        perror("打开设备文件失败");
        return 1;
    }

    // 初始化音量
    long volume = get_playback_volume("hw:0", "Analog");

    while (1) {
        snd_pcm_sframes_t frames = snd_pcm_readi(capture, buffer, period); // 从PCM设备读取数据
        if (frames < 0) {
            fprintf(stderr, "Error from read: %s\n", snd_strerror(frames));
            snd_pcm_recover(capture, frames, 0);
            continue;
        }

        int status = SnowboyDetectRunDetection(detector, (int16_t *)buffer, snd_pcm_frames_to_bytes(capture, frames) / sizeof(int16_t), 0);

        if (status > 0) { // 检测到唤醒词
            if (!recording) {
                printf("检测到唤醒词，开始录音\n");
                recording = 1; // 开始录音
                silence_start = 0; // 重置静音计时
                pcm_file = open_memstream(&audio, &audio_size); // 打开内存文件
                if (!pcm_file) {
                    handle_error("open_memstream", capture, detector);
                }
            }
        }

        if (recording) {
            if (status == -2) { // 静音
                if (silence_start == 0) {
                    silence_start = time(NULL); // 记录静音开始时间
                } else if (time(NULL) - silence_start >= SILENCE_THRESHOLD) {
                    printf("静音超过2秒，停止录音\n");
                    recording = 0; // 停止录音
                    silence_start = 0; // 重置静音计时
                    fclose(pcm_file); // 关闭内存文件
                    pcm_file = NULL;

                    if (audio_size > 0) {
                        // 暂停录音
                        snd_pcm_drop(capture);
                        // 识别语音
                        char *text = speech_to_text(audio, audio_size);
                        if (text) {
                            puts(text);
                            // 先执行控制命令
                            int command_executed = execute_command(text, ac_fp, led_fp1, led_fp2, led_fp3, &hazard_lights_on, &volume);
                            if (!command_executed) {
                                // 如果控制命令未执行或没有 answer 字段，执行 create_conversation 并获取结果
                                char *answer = chat(conv_id, text, authtoken->valuestring);
                                if (answer) {
                                    puts(answer);
                                    // 执行命令并获取结果
                                    execute_command(answer, ac_fp, led_fp1, led_fp2, led_fp3, &hazard_lights_on, &volume);
                                    // 播放TTS
                                    text_to_speech(answer);
                                    free(answer); // 释放answer
                                } else {
                                    // 没有 answer 字段也需要唤醒 create_conversation
                                    char *conversation_answer = chat(authtoken->valuestring, conv_id, text);
                                    if (conversation_answer) {
                                        puts(conversation_answer);
                                        text_to_speech(conversation_answer);
                                        free(conversation_answer);
                                    }
                                }
                            }
                            free(text); // 释放text
                        }
                        free(audio); // 释放音频缓冲区
                        audio = NULL;
                        audio_size = 0;
                        // 恢复录音
                        snd_pcm_prepare(capture);
                    }
                }
            } else {
                silence_start = 0; // 重置静音计时
            }

            if (pcm_file) {
                fwrite(buffer, snd_pcm_frames_to_bytes(capture, frames), 1, pcm_file); // 将音频数据写入内存文件
            }
        }

        if (hazard_lights_on && time(NULL) - last_blink_time >= 1) { // 如果双闪灯开启并且时间间隔达到1秒
            blink_state = !blink_state; // 切换闪烁状态
            fprintf(led_fp1, "%d", blink_state); // 设置LED1亮度
            fflush(led_fp1);
            fprintf(led_fp3, "%d", blink_state); // 设置LED3亮度
            fflush(led_fp3);
            last_blink_time = time(NULL); // 更新上一次闪烁时间
        }
    }

    // 清理资源
    fclose(ac_fp);
    fclose(led_fp1);
    fclose(led_fp2);
    fclose(led_fp3);
    free(conv_id);
    cJSON_Delete(config);
    record_close(capture);
    SnowboyDetectDestructor(detector);
    free(buffer);

    return EXIT_SUCCESS;
}
